#!/bin/sh
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

# Author: Lars Michelsen <lm@mathias-kettner.de>
#         Florian Heigl <florian.heigl@gmail.com>
#  Christian Zigotzky <chzigotzky@xenosoft.de>

# NOTE: This agent has been adapted from the Checkmk FreeBSD agent.

inpath() {
    # replace "if type [somecmd]" idiom
    # 'command -v' tends to be more robust vs 'which' and 'type' based tests
    command -v "${1:?No command to test}" >/dev/null 2>&1
}

get_epoch() {
    date +%s 2>/dev/null ||
        perl -e 'print($^T."\n");'
}

# Remove locale settings to eliminate localized outputs where possible
export LC_ALL=C
unset LANG

export MK_LIBDIR="/change/me/"
export MK_CONFDIR="/change/me"

# Optionally set a tempdir for all subsequent calls
#export TMPDIR=

# Make sure, locally installed binaries are found
PATH=$PATH:/usr/pkg/bin

# All executables in PLUGINSDIR will simply be executed and their
# ouput appended to the output of the agent. Plugins define their own
# sections and must output headers with '<<<' and '>>>'
PLUGINSDIR=$MK_LIBDIR/plugins

# All executables in LOCALDIR will by executabled and their
# output inserted into the section <<<local>>>. Please refer
# to online documentation for details.
LOCALDIR=$MK_LIBDIR/local

if inpath sudo && [ "$(whoami)" != "root" ]; then
    ROOT_OR_SUDO="sudo --non-interactive"
else
    ROOT_OR_SUDO=""
fi
export ROOT_OR_SUDO

# close standard input (for security reasons) and stderr
if [ "$1" = -d ]; then
    set -xv
else
    exec </dev/null 2>/dev/null
fi

section_misc_sections() {

    echo "<<<check_mk>>>"
    echo "Version: 2.5.0b1"
    echo "AgentOS: netbsd"
    echo "Hostname: $(hostname)"
    echo "AgentDirectory: $MK_CONFDIR"
    echo "DataDirectory: $MK_VARDIR"
    echo "SpoolDirectory: $SPOOLDIR"
    echo "PluginsDirectory: $PLUGINSDIR"
    echo "LocalDirectory: $LOCALDIR"
    echo "OSType: unix"
    echo "OSName: $(uname -s)"
    echo "OSVersion: $(uname -r)"

    echo '<<<df>>>'
    df -kPt ffs | sed -e 's/^\([^ ][^ ]*\) \(.*\)$/\1 ffs \2/' | sed 1d

    # processes including username, without kernel processes
    echo '<<<ps>>>'
    echo "[time]"
    get_epoch
    echo "[processes]"
    ps ax -ww -o user,vsz,rss,pcpu,command | sed -e 1d -e 's/ *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) */(\1,\2,\3,\4) /'

    echo '<<<cpu>>>'
    printf "%s %s %s\n" \
        "$(sysctl -n vm.loadavg | tr -d '{}')" \
        "$(top -b -n 1 | grep -E '^[0-9]+ processes' | awk '{ print $3"/"$1 }')" \
        "$(sysctl -n hw.ncpu)"

    echo '<<<uptime>>>'
    echo "$(get_epoch) - $(sysctl -n kern.boottime | cut -d' ' -f 4,7 | tr ',' '.' | tr -d ' ')" | bc

    echo '<<<netctr>>>'
    # BI= Bytes in
    # PI= Packets in
    # EI= Errors in
    # EO= Errors out
    # BO= Bytes out
    # PO= Packets out
    # CO= Colls

    Z1=1
    Z2=p

    date +%s
    while [ $Z1 -lt 15 ]; do
        BI=$(netstat -inb | grep -v -E Name | grep Link | awk '{ print $1" "$5 }' | sed -ne $Z1$Z2)
        PI=$(netstat -in | grep -v -E Name | grep Link | awk '{ print $5 }' | sed -ne $Z1$Z2)
        EI=$(netstat -in | grep -v -E Name | grep Link | awk '{ print $6 }' | sed -ne $Z1$Z2)
        FF1="0 0 0 0 0"
        BO=$(netstat -inb | grep -v -E Name | grep Link | awk '{ print $6 }' | sed -ne $Z1$Z2)
        PO=$(netstat -in | grep -v -E Name | grep Link | awk '{ print $7 }' | sed -ne $Z1$Z2)
        EO=$(netstat -in | grep -v -E Name | grep Link | awk '{ print $8 }' | sed -ne $Z1$Z2)
        CO=$(netstat -in | grep -v -E Name | grep Link | awk '{ print $9 }' | sed -ne $Z1$Z2)
        FF2="0 0"
        if [ "$PI" -gt "0" ]; then
            echo "$BI $PI $EI $FF1 $BO $PO $EO $FF2 $CO $FF2"
        fi
        Z1=$((Z1 + 1))
    done

    # IPMI-Data (Fans, CPU, temperature, etc)
    # needs the sysutils/ipmitool or freeipmi and kldload ipmi.ko
    if inpath ipmitool; then
        echo '<<<ipmi>>>'
        ipmitool sensor list |
            grep -v 'command failed' |
            sed -e 's/ *| */|/g' -e "s/ /_/g" -e 's/_*$//' -e 's/|/ /g' |
            grep -v -E '^[^ ]+ na ' |
            grep -v ' discrete '
    elif inpath ipmi-sensors; then
        echo '<<<ipmi_sensors>>>'
        if ipmi-sensors --help | grep -q legacy-output; then
            IPMI_FORMAT="--legacy-output"
        else
            IPMI_FORMAT=""
        fi
        if ipmi-sensors --help | grep -q " \-\-groups"; then
            IPMI_GROUP_OPT="-g"
        else
            IPMI_GROUP_OPT="-t"
        fi
        for class in Temperature Power_Unit Fan; do
            ipmi-sensors ${IPMI_FORMAT} --sdr-cache-directory /var/cache ${IPMI_GROUP_OPT} "${class}" | sed -e 's/ /_/g' -e 's/:_/ /g' -e 's@ \([^(]*\)_(\([^)]*\))@ \2_\1@'
            # In case of a timeout immediately leave loop.
            if [ $? = 255 ]; then break; fi
        done
    fi

    if inpath mailq && getent passwd postfix >/dev/null 2>&1; then
        echo '<<<postfix_mailq>>>'
        ${ROOT_OR_SUDO} mailq | tail -n 6
    fi
}

run_plugins() {
    (
        cd "${PLUGINSDIR}" || return
        for script in "./"*; do
            [ -x "${script}" ] && "${script}"

        done
    )
}

run_local_checks() {
    (
        cd "${LOCALDIR}" || return
        echo '<<<local:sep(0)>>>'
        for script in "./"*; do
            [ -x "${script}" ] && "${script}"
        done
    )
}

run_mrpe_plugins() {
    if [ -e "$MK_CONFDIR/mrpe.cfg" ]; then
        echo '<<<mrpe>>>'
        # SC2162: read without -r will mangle backslashes.
        # The following suppression was added when we enabled the corresponding shellcheck.
        # It may well be that "read -r" would be more appropriate.
        # shellcheck disable=SC2162
        grep -Ev '^[[:space:]]*($|#)' "$MK_CONFDIR/mrpe.cfg" |
            while read descr cmdline; do
                PLUGIN=${cmdline%% *}
                OUTPUT=$(eval "$cmdline")
                printf "(%s) %s %s %s" "${PLUGIN##*/}" "$descr" "$?" "$OUTPUT" | tr \\n \\1
                printf "\n"
            done
    fi
}

main() {

    section_misc_sections

    run_plugins

    run_local_checks

    run_mrpe_plugins

    return 0
}

[ -n "${MK_SOURCE_AGENT}" ] || main "$@"
